파이썬 기초

파이썬 권장 스타일

파이썬을 코딩할 때에는 가독성을 위해 PEP 8에서 명시하는 권장 스타일을 따르는 것이 좋다.

  • 한 줄은 79글자로 제한하기
  • import는 파일의 맨 위에 적고 내장 모듈, 제3자 모듈, 직접 만든 모듈 순서로 불러들이기
  • 인스턴스 메소드의 첫 인자는 self로 쓰고, 클래스 메소드의 첫 인자는 cls로 쓰기
  • 할당 연산자(=)의 앞뒤로 공백 넣기
MODULE_CONSTANT_NAME = 0
import module_name
class ClassName()
def function_name()
variable_name = 0
_protected_attribute_name = 0
__hidden_attribute_name = 0


파이썬 시맨틱

파이썬은 가독성과 명료성, 그리고 명백함을 강조한다. 어떤 사람들은 파이썬을 실행 가능한 의사코드(Executable Pseudocode)라고 표현하기도 한다.

def factorial(x):
return 1 if x == 0 else x * factorial(x - 1)

들여쓰기

파이썬은 C, C++, Java, 등과 같은 언어와는 달리 중괄호 대신 공백문자를 사용해서 코드를 구조화한다. 콜론은 코드 블록의 시작을 의미하며 블록이 끝날 때까지 블록 안에 있는 코드는 모두 같은 크기만큼 들여써야 한다. 공백문자가 의미를 가지는 파이썬의 이러한 스타일 제한은 쓰는 사람에 관계 없이 통일성을 유지하게 하며, 그 결과 가독성이 향상될 수 있는 장점이 있다.

for x in array:
if x < pivot:
less.append(x)
else:
greater.append(x)

모든 것은 객체

모든 숫자, 문자열, 자료구조, 함수, 클래스, 모듈 등은 파이썬 인터프리터에서 파이썬 객체라고 하는 어떤 상자 안에 저장된다. 객체 모델의 일관성은 파이썬의 중요한 특징이며, 파이썬에는 원시 타입(Primitive Type)이 존재하지 않고 모든 것이 객체로 취급된다.

a = 10 # a에 10이 할당된 것이 아니라 a가 10이 저장된 상수 객체를 가리킨다.
a = 20 # a의 값이 10에서 20으로 바뀐게 아니고, 20이 저장된 상수 객체로 바뀐 것이다.

주석

뒤에 오는 글자는 모두 파이썬 인터프리터에서 무시되며, 이를 이용해 코드의 주석을 달 수 있다.

# if len(line) == 0:
# continue

참조에 의한 전달(Call by Reference)

파이썬에서 변수에 값을 대입하면 대입연산자 오른쪽에 있는 객체에 대한 참조를 생성하게 된다. 함수에 인자로 객체를 넘기면 복사가 일어나지 않고 그 객체에 대한 참조만 전달된다.

a = [1,2,3]
b = a
a.append(4)
b # [1,2,3,4]
def append_element(some_list, element):
some_list.append(element)
data = [1,2,3]
append_element(data, 4)
data # [1,2,3,4]

동적 참조

C++, Java 등과 같은 다른 컴파일 언어와는 대조적으로 파이썬에서 객체의 참조는 자료형이 정해져 있지 않다. 따라서 다음과 같은 코드는 전혀 문제가 되지 않는다.

a = 5
type(a) # int
a = 'foo'
type(a) # str

강한 타입

JavaScript 같은 다른 언어에서는 정수 5가 문자열로 변환되어 ‘55’라는 문자열을 반환한다. 하지만 파이썬은 모든 객체는 특정한 자료형(또는 클래스)을 가지며 다음의 코드는 실행되지 않는다.

'5' + 5 # TypeError: can only concatenate str (not "int") to str

파이썬의 경우 다음과 같은 명백한 상황에서만 묵시적인 변환을 수행하는 자료형을 가진 언어이다.

a = 4.5
b = 2
print('a: %s, b: %s' % (type(a), type(b))) #a: <class 'float'>, b: <class 'int'>
a / b # 2.25

isinstance 함수를 이용하면 어떤 객체가 무슨 자료형인지 검사할 수 있다.

a = 5
isinstance(a, int)
isinstance(a, (int, float))

속성과 메소드

파이썬에서 객체는 일반적으로 그 객체 내부에 저장되는 속성(파이썬 객체)과 그 객체의 내부 데이터에 접근할 수 있는 함수인 메소드를 가진다. 속성과 메소드는 obj.attribute_name 같은 문법으로 접근할 수 있다. 속성과 메소드는 getattr 함수를 통해 그 이름으로 접근할 수도 있다.

a = 'foo'
getattr(a, 'split')

# 함수 vs. 메소드 #

# 함수는 매개변수를 통한 값 전달과 특정 기능을 한다.
len(some_list)

# 메소는 특정 자료와 연관지어 기능을 한다.
some_list.sort()
some_list.pop()
some_list.clear()

덕 타이핑

덕 타이핑(Duck Typing)은 동적 타이핑의 한 종류로, 객체의 변수 및 메소드의 집합이 객체의 타입을 결정하는 것을 말한다. 객체의 자료형에는 관심이 없고 그 객체가 어떤 메소드를 지원하는지만 알고 싶은 경우가 있다. 예를 들어 어떤 객체가 iterator를 구현해서 순회가 가능한 객체인지 알고 싶은 경우 다음과 같다.

def isiterable(obj):
try:
iter(obj)
return True
except TypeError: # not iterable
return False

if not isinstance(x, list) and isiterable(x):
x = list(x)

모듈 import

파이썬에서 모듈은 다른 .py 파일에서 추가해서 사용할 수 있는 함수와 변수 선언을 담고 있는 .py파일이다. 예를 들어 some_module.py에서 정의한 변수와 함수에 접근하려면 같은 디렉터리에 있는 다른 파일에서 다음처럼 작성한다. as 예약어를 사용하면 모듈을 다른 이름으로 import 할 수 있다.

# import a : a 모듈을 불러오겠다.
# a 모듈 안에있는 b 함수를 사용하기 위해선 a.b() 꼴로 사용하면 된다.
import some_module as sm
result = sm.f(5)
pi = sm.PI

# some_module.py
PI = 3.14159
def f(x):
return x + 2
def g(a, b):
return a + b

또는 다음처럼 작성할 수도 있다.

# from a import b : a 모듈(혹은 패키지)에서 b 함수를 가져오겠다.
# b를 사용하기 위해선 b() 꼴 로 사용 가능하다.
from some_module import f, g, PI
result = g(5, PI)

가변 객체(Mutable Object) 및 불변 객체(Immutable Object)

파이썬에서 리스트, 딕셔너리 또는 사용자 정의 클래스 같은 대부분의 객체는 변경이 가능하다. 즉, 객체나 값의 내용을 바꿀 수 있는 가변 객체이다. 값을 수정할 때는 바뀐 값이 저장된 새로운 객체를 생성하고 참조 대상을 새 객체로 옮기는 방식으로 동작한다. 이와 같은 특징 때문에 파이썬은 순수 객체지향 언어라고 할 수 있다. 반면 문자열이나 튜플은 값을 변경할 수 없는 불변 객체이다.

a_list = ['foo', 2, [4, 5]]
a_list[2] = (3, 4)
print(a_list) # ['foo', 2, (3, 4)]

a_tuple = (3, 5, (4, 5))
a_tuple[1] = 'four' # TypeError: 'tuple' object does not support item assignment


파이썬 이항연산자

이항연산자와 산술연산자는 타 프로그래밍 언어와 거의 동일하다.

Operation Description
a + b a와 b를 더한다.
a - b a에서 b를 뺀다.
a ∗ b a에 b를 곱한다.
a / b a를 b로 나눈다.
a // b a를 b로 나눈 몫을 취한다.
a % b a를 b로 나눈 나머지를 취한다.
a ∗∗ b a의 b승을 구한다.
a & b a와 b가 모두 True일 경우 True를 반환한다. 정수일 경우 비트 단위 AND를 구한다.
a ∣ b a 혹은 b가 True일 경우 True를 반환한다. 정수일 경우 비트 단위 OR을 구한다.
a ^ b a 혹은 b 중 하나만 True일 경우 True를 반환한다. 정수일 경우 비트 단위 EXCLUSIVE-OR을 구한다.
a == b a와 b가 같은 경우 True
a != b a와 b가 다를 경우 True
a<=b, a<b 각각 a가 b이하일 경우, a가 b 미만일 경우 True
a>b, a>=b 각각 a가 b 초과일 경우, a가 b 이상일 경우 True
a is b a와 b가 같은 파이썬 객체를 참조할 경우 True
a is not b a와 b가 다른 파이썬 객체를 참조할 경우 True

두 참조 변수가 같은 객체를 가리키고 있는지 검사하려면 is 예약어를 사용하며, 이는 == 연산자와 다르다는 것을 기억하자. is not을 사용하면 두 객체가 같지 않은지 검사할 수 있다.

a = [1, 2, 3]
b = a
c = list(a) # 새 리스트 생성

print(a is b) # True
print(a is not c) # True
print(a == c) # True


파이썬 입출력

출력

print() 함수를 사용한다.

name = "손흥민"
backnum = 7
print("이름: %s 등번호: %d" % (name, backnum)) # 이름: 손흥민 등번호: 7
print("이름: {} 나이: {}".format(name, backnum))

입력

input() 함수를 사용하며, 입력값이 한 개인 경우는 다음과 같다.

n = int(input()) # 정수값 변환을 위한 캐스팅
str = input()

공백문자를 구분자로 하여 한 줄에 입력값을 두 개 이상 입력받는 경우에는 map() 함수를 이용한다.

a, b, c = map(int, input().split())


파이썬 흐름제어

if, elif, else

if 문은 조건을 검사하여 그 조건이 True일 경우 if 블록 내의 코드를 수행한다. if문은 부가적으로 하나 이상의 elif 블록과 다른 모든 조건이 False인 경우 수행될 else 블록을 가질 수 있다.

x = 10
if x < 0:
print('It is Negative')
elif x == 0:
print('Equal to Zero')
elif 0 < x < 5:
print('Positive but smaller than 5')
else:
print('Positive and Larger than or equal to 5')

파이썬에서는 if-else 블록을 한 줄로 표현할 수 있다.

x = 5
print('Positive' if x >= 0 else 'Negative') # Positive

for 반복문

for 반복문은 리스트나 튜플 같은 컬렉션이나 이터레이터를 순회한다. for 문은 continue 예약어를 사용해서 남은 블록을 건너뛰고 다음 순회로 넘어갈 수도 있고, break 예약어를 사용해서 빠져나갈 수도 있다.

sequence = [1, 2, None, 4, None, 5]
total = 0
for value in sequence:
if value is None:
continue
total += value

print(total) # 12
string = 'Python'
for i in range(len(string)):
print(string[i], end='') # Python

while 반복문

while 반복문은 조건을 명시하고 해당 조건이 False가 되거나 break문을 사용해서 명시적으로 반복을 끝낼 때까지 블록 안의 코드를 수행한다.

x = 256
total = 0
while x > 0:
if total > 500:
break
total += x
x = x // 2

print(total) # 504

pass

pass 문은 블록 안에서 어떤 작업도 실행하지 않을때 사용된다.

if x < 0 :
pass

예외처리

견고한 프로그램을 작성하려면 파이썬의 오류나 예외를 잘 처리해야 한다. 이를 위해 try/except 블록을 사용하면 된다. 예외를 무시하지 않고, 해당 블록의 코드가 성공적으로 수행되었는지의 여부와 관계없이 실행시키고 싶은 코드는 finally 블록을 사용해서 적는다.

def attempt_float(x):
try:
return float(x)
except (TypeError, ValueError): # 튜플을 사용하여 여러 예외를 한 번에 처리 가능
return x
f = open(path, 'w')
try:
write_to_file(f)
finally:
f.close()


인덱스 슬라이싱

리스트와 같은 자료형(배열, 튜플 등)은 색인 연산자 [] 안에 [시작위치(start):끝위치(stop):간격(step)]을 지정하여 사용할 수 있다. 색인의 시작 위치에 있는 값은 포함되지만 끝 위치에 있는 값은 포함되지 않는다. 따라서 슬라이싱 결과 개수는 stop - start이다. 간격 값으로 -1을 사용하면 리스트나 튜플을 역순으로 반환한다.

str = "123456"
print(str[1::2]) # 246
print(str[::-1]) # 654321
Share